﻿using EasyDentalMail.DAO;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using EasyDentalMail.View;
using System.Text.RegularExpressions;

namespace EasyDentalMail.BO
{
    public class GoogleBO
    {
        private UserCredential credential;
        private CalendarService cServ;
        private CalendarListEntry calEntry;

        private GoogleDAL goDAL = new GoogleDAL();

        public GoogleBO()
        {
            if (cServ == null)
                criarServicoCalendar();
            if (calEntry == null)
            {
                var calList = cServ.CalendarList.List().Execute();
                if (calList != null && calList.Items != null && calList.Items.Count() > 0)
                    calEntry = calList.Items.Where(p => p.AccessRole == "owner").SingleOrDefault();
            }
        }

        public GoogleView pegarGoogle(AgendaView ag)
        {
            return goDAL.getGoogle(ag);
        }


        private List<GoogleView> listar()
        {
            return goDAL.listar();
        }

        private async Task conectarGoogle()
        {
            credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                   new ClientSecrets
                   {
                       ClientId = "142603010188-radsv5a439les8hamq0d9esmge7cn0bs.apps.googleusercontent.com",
                       ClientSecret = "asFEk11i470T10N1eGMg9wrY"
                   },
                   new[] { CalendarService.Scope.Calendar },
                   "user", CancellationToken.None, new FileDataStore("Calendar.Gravado1"));
        }

        private void criarServicoCalendar()
        {
            conectarGoogle().Wait();
            cServ = new CalendarService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "EasyDentalMail",
            });
        }

        public void removerEventoGoogleCalendar(ProgressBar pgb, Label lbl)
        {
            lbl.Text = "Removendo Agenda Google";
            if (Form.ActiveForm != null)
                Form.ActiveForm.Refresh();
            List<GoogleView> lstGoo = listar();
            List<GoogleView> lstDel = goDAL.listarDelete();
            pgb.Maximum = lstDel.Count();
            foreach (GoogleView goC in lstDel)
            {
                pgb.PerformStep();
                if (Form.ActiveForm != null)
                    Form.ActiveForm.Refresh();
                Thread.Sleep(100);
                if (cServ != null && calEntry != null)
                {
                    try
                    {
                        string valor = cServ.Events.Delete(calEntry.Id, goC.CalendarId).Execute();
                        goDAL.deletar(goC.Id);
                    }
                    catch
                    {
                    }
                }
            }
            lbl.Text = "";
            pgb.Value = 0;
            if (Form.ActiveForm != null)
                Form.ActiveForm.Refresh();
        }

        private Event montarEvento(AgendaView ag)
        {
            Event ev = new Event
            {
                Start = new EventDateTime
                {
                    DateTime = DateTime.Parse(createData(ag.Data, ag.HoraInicio))
                },
                End = new EventDateTime
                {
                    DateTime = DateTime.Parse(createData(ag.Data, ag.HoraFim))
                },
                Summary = ag.Nome + " " + ag.Telefone1,
                Description = AgendaBO.montarDescricao(ag)
            };
            if (!string.IsNullOrEmpty(ag.Email) && Regex.IsMatch(ag.Email, @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z"))
            {
                ev.Attendees = new List<EventAttendee>();
                ev.Attendees.Add(new EventAttendee
                {
                    Email = ag.Email
                });
            }
            return ev;
        }

        private void insertGoogleCalendar(AgendaView ag, string calendarId)
        {
            GoogleView gooCalend = new GoogleView
            {
                CalendarId = calendarId,
                Data = ag.Data,
                HoraInicio = ag.HoraInicio,
                IdUnidade = ag.Id_Unidade,
                IdPrestador = ag.Id_Prestador
            };
            goDAL.insert(gooCalend);  
        }

        public void cadastrarAgenda(ProgressBar pgb, Label lbl)
        {
            AgendaBO agBO = new AgendaBO();
            List<AgendaView> lstAgenda = agBO.listarAgendamentos();
            pgb.Maximum = lstAgenda.Count();

            lbl.Text = "Cadastrando Agenda Google";
            if (Form.ActiveForm != null)
                Form.ActiveForm.Refresh();
            foreach (AgendaView ag in lstAgenda)
            {
                pgb.PerformStep();
                if (Form.ActiveForm != null)
                    Form.ActiveForm.Refresh();
                Thread.Sleep(100);
                GoogleView gooC = pegarGoogle(ag);
                if (gooC != null)
                    continue;
                
                Event ev = montarEvento(ag);
                if (calEntry == null || cServ == null)
                    return;
                try
                {
                    var cInsert = cServ.Events.Insert(ev, calEntry.Id).Execute();
                    insertGoogleCalendar(ag, cInsert.Id);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
            lbl.Text = "";
            pgb.Value = 0;
            if (Form.ActiveForm != null)
                Form.ActiveForm.Refresh();
        }

        private string createData(DateTime data, int? horaInicio)
        {
            string str = "{0} {1}";
            return string.Format(str, data.ToString("yyyy-MM-dd"), Utils.convertHora(horaInicio));
        }

        public void pegarAgendamentosGoogle(ProgressBar pgb, Label lbl)
        {
            var getList = cServ.Events.List(calEntry.Id);
            lbl.Text = "Buscando Agenda Google";
            if (Form.ActiveForm != null)
                Form.ActiveForm.Refresh();
            getList.TimeMin = DateTime.Today;
            Events evts = getList.Execute();
            if (evts != null && evts.Items != null && evts.Items.Count() > 0)
            {
                List<GoogleView> lstGoo = listar();
                List<string> lstId = lstGoo.Select(p => p.CalendarId).ToList();
                List<Event> evtsFilter = evts.Items.Where(p => !lstId.Contains(p.Id)).ToList();
                pgb.Maximum = evtsFilter.Count();
                AgendaBO agBO = new AgendaBO();
                foreach (Event evt in evtsFilter)
                {
                    try
                    {
                        pgb.PerformStep();
                        if (Form.ActiveForm != null)
                            Form.ActiveForm.Refresh();
                        Thread.Sleep(100);
                        AgendaView ag = agBO.convert(evt);
                        agBO.inserir(ag);
                        insertGoogleCalendar(ag, evt.Id);
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
            lbl.Text = "";
            pgb.Value = 0;
            if (Form.ActiveForm != null)
                Form.ActiveForm.Refresh();
        }
    }
}
